<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * class是一个关键词
    *
    * 相当于创建了一个叫Foo的构造函数
    *
    * class Foo{} 与 function Foo(){} 的对比
    *   class Foo             相当于     function Foo
    *   constructor构造器      相当于     (){}
    *
    *
    * */

    //es6的写法 内部隐藏了代码的实现，不用写prototype
    class Foo{ //所有的代码都在这个类当中，更具有完整性
        constructor(a) {
            this.a = a
            this.b = 2
        }
        f1(){
            console.log(this.a)
        }
        f2(x){
            console.log(this.b + x)
        }
    }

    //上面完全等价于下面

    function Foo1(a){
        this.a = a
        this.b = 2
    }
    Foo1.prototype.f1 = function (){
        console.log(this.a)
    }
    Foo1.prototype.f2 = function (x){
        console.log(this.b + x)
    }

    //分别new上下两种方法
    let obj = new Foo(3)
    let obj1 = new Foo1(3)



    /*
    * 继承
    *
    *   有人这个构造函数，每一个人都有名字
    *
    *   有动物这个构造函数，每一个动物都有脉搏
    *
    *   这两个类别有什么关系？
    *   继承，人属于动物
    *
    *   静态方法static：
    *       方法前面添加static（静态的意思）
    *       静态方法不允许实例执行，但是可以通过构造函数直接访问。静态方法内部不能使用this，因为静态方法压根不允许实例对象使用，
    *       方法都不存在，也就没有使用this的意义
    *       静态方法相当于直接给构造函数添加一个方法属性，而不是在构造函数的原型（prototype）中添加
    *   静态方法的作用：
    *       一般对构造函数内部初始化的时候进行修饰，完完全全是构造函数的内部方法，对外不透明，非常安全
    *
    * */

    //父类
    class Animal{
        constructor(){
            this.maibo = "true"
            this.sex = "girl"
            this.age = 40
        }
        say(){
            this.age++
        }
    }

    //子类 如何让 子类（人） 继承 父类（动物） 的属性
    class Person extends Animal{
        constructor(){
            super() //但凡要继承，第一行都需要先执行 super，super是父类中的constructor，super执行相当于添加属性到子类
            this.name = "小三"
            this.sex = "boy" //如果有一个和父类同样的方法，子类的方法会覆盖父类的方法
            this.age = 20
            Person.zhixing()
        }
        kill(){ //如果子类当中有个kill属性，修改this.maibo，也只能在由子类实例出来的实例对象person调用kill方法后，修改实例对象person的maibo属性
            this.maibo = false
        }
        static zhixing(){ //虽然由构造函数Person实例出来的实例对象person不能使用该静态方法，但是可以通过上面的Person.zhixing直接访问
            console.log("执行了")
        }
    }

    let person = new Person()
    console.log(person) //一开始person里面的age是20，maibo是true，因为构造函数Person的age就是20，maibo就是true

    //下面的几种方法的调用，都只能在实例对象person调用该方法之后，修改实例对象person身上的相对应属性，而不能修改实例对象person的构造函数Person身上的属性
    person.say() //say方法执行之后，person的age会加一
    //因为构造函数Person继承了构造函数Animal的say属性，构造函数Person又实例出了person这个实例对象，所以person也有say方法，当person调用say时，
    //this.age++，就改变了实例对象person自身的age
    person.kill() //修改了实例对象person的maibo属性






</script>
</body>
</html>